<template>
    <div class="markdown-outline p-4 border-gray-200 overflow-y-hidden">
        <h3 v-show="showoutline" class="text-lg font-semibold mb-4">文章大纲</h3>
        <ul class="outline-list space-y-1">
            <template v-for="(item, index) in outlineItems" :key="index">
                <li :class="['outline-item', item.active ? 'text-blue-500 font-medium' : 'text-gray-600']"
                    :style="`margin-left: ${((item.level - min_level) * 12)}px`"
                    @click="scrollToHeading(item.id)">
                    {{ item.text }}
                    <span class="inline-block w-4 text-gray-400">#{{ item.level }}</span>

                </li>
            </template>
        </ul>
    </div>
</template>

<script setup>
const props = defineProps({
    content: {
        type: String,
        default: '',
        required: false
    }
});

const showoutline = ref(false)
const outlineItems = ref([]);
const activeHeadingId = ref('');
const min_level = ref(6)

import CryptoJS from 'crypto-js'

// 从markdown内容中提取标题信息
const extractHeadings = (content) => {
    const headings = [];

    let dot_number = 0, dollar_number = 0
    for (let i = 0; i < content.length; ++ i) {
        while (content[i] == '`') { dot_number++; i++; }
        while (content.substring(i, i + 2) == '$$') { dollar_number++; i+=2; } // 必须在 content[i] == '$' 之前，不然会误判​
        while (content[i] == '$') { dollar_number++; i++; }

        if (dot_number % 2 == 0 && dollar_number % 2 == 0) {
            // console.log('dot_number', dot_number)
            // console.log('dollar_number', dollar_number)
            let sharp_number = 0;
            let text = ''
            while (content[i] == '#') { sharp_number++; i++; }
            if (sharp_number > 0 && content[i] == ' ') {
                while (content[i] == ' ' && i < content.length) { i++; }
                if (content[i] == '\n' || i == content.length) { continue }
                
                let start = i
                while (content[i] != '\n' && i < content.length) { i++; }
                text = content.substring(start, i)

                min_level.value = Math.min(sharp_number, min_level.value)
                
                headings.push({
                    level: sharp_number,
                    text,
                    id: CryptoJS.MD5(text).toString() // 生成唯一ID
                });
            }
        }
    }
    console.log(headings)
    return headings;
};

// 监听内容变化，更新大纲
watch(
    () => props.content, 
    (newContent) => {
        outlineItems.value = extractHeadings(newContent);
        showoutline.value = true
    }
);

// 滚动到指定标题
const scrollToHeading = (id) => {
    const element = document.getElementById(id);
    if (element) {
        element.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
};

// 监听滚动事件，更新当前激活的标题
const handleScroll = () => {
    const headings = document.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]');
    let current = '';

    headings.forEach(heading => {
        const headingTop = heading.offsetTop;
        // 考虑到顶部导航栏的高度，这里假设为60px
        if (window.scrollY >= headingTop - 60) {
            current = heading.getAttribute('id');
        }
    });

    if (current && current !== activeHeadingId.value) {
        activeHeadingId.value = current;
        // 更新大纲中激活的标题
        outlineItems.value.forEach(item => {
            item.active = item.id === current;
        });
    }
};

onMounted(() => {
    // 添加滚动事件监听
    window.addEventListener('scroll', handleScroll);

    return () => {
        // 组件卸载时移除监听
        window.removeEventListener('scroll', handleScroll);
    };
});
</script>

<style scoped>
.outline-list {
    list-style-type: none;
    padding-left: 0;
}

.outline-item {
    cursor: pointer;
    transition: color 0.2s;
    line-height: 1.6;
}

.outline-item:hover {
    color: #3b82f6;
}
</style>